import pygame

from pygame.locals import *
#some widgets

class Label:
    """A wrapper to manage rendering text to the screen."""
    def __init__(self, surface, x, y, font, content):
        """Initialize the label with the specified parameters"""
        self.surface = surface
        self.x = x
        self.y = y
        self.font = font
        self.content = content
        self.calculateClearSurface()

    def calculateClearSurface(self):
        """Returns a surface object that is of the exact dimensions of this text, but blank"""
        self.height, self.width = (self.font.size(self.content)[1], self.font.size(self.content)[0])
        self.clearSurface = pygame.Surface((self.width, self.height))
        self.clearSurface.fill((0, 0, 0))
        return self.clearSurface

    def drawSelf(self):
        """Render the text held in the label to a surface, then blit it to the game screen."""
        self.height, self.width = (self.font.size(self.content)[1], self.font.size(self.content)[0])

        height = self.height
        width = self.width

        tempSurface = pygame.Surface((width, height))
        tempSurface.fill((0, 0, 0))

        self.clearSurface = tempSurface
        self.surface.blit(self.calculateClearSurface(), (self.x, self.y))
        
        tempSurface.blit(self.font.render(self.content, True, (255, 255, 255)), (0, 0))

        self.surface.blit(tempSurface, (self.x, self.y))

    def updateContent(self, content):
        """Recalculates the clear surface of the label and its dimensions"""
        if content is None:
            content = self.content

        self.calculateClearSurface()
        self.surface.blit(self.clearSurface, (self.x, self.y))
        self.content = content
        #self.drawSelf()

class ChoiceList:
    """A UI class that allows the player to pick one of several choices from the screen."""
    def __init__(self, surface, x, y, choices, font, selectedItemFont):
        """Creates a ChoiceList with the specified parameters."""
        #expects font and selectedItemFont to be SysFonts!
        self.surface = surface
        self.x = x
        self.y = y
        self.choices = choices
        self.font = font
        self.selectedItemFont = selectedItemFont
        self.selectedItemIndex = 0

        #figure out how wide we are
        longestChoice = self.choices[0]
        for choice in self.choices:
            if len(choice) > len(longestChoice):
                longestChoice = choice

        self.width = max(self.font.size(longestChoice)[0], self.selectedItemFont.size("> %s" % (longestChoice))[0])

    def getSelectedChoice(self):
        """Returns the selecfted choice as a string"""
        return self.choices[self.selectedItemIndex]

    def selectItem(self, itemIndex):
        """Selects the item at the index specified"""
        self.selectedItemIndex = itemIndex

    def selectNextItem(self):
        """Selects the item after the current selection. Wraps around to the first if the last item is currently selected"""
        self.selectedItemIndex += 1
        if len(self.choices) - 1 < self.selectedItemIndex:
            self.selectedItemIndex = 0
        self.drawSelf()

    def selectPreviousItem(self):
        """Selects the item before the current selection. Wraps around to the last if the first item is currently selected"""
        self.selectedItemIndex -= 1
        if self.selectedItemIndex < 0:
            self.selectedItemIndex = len(self.choices) - 1
        self.drawSelf()

    def drawSelf(self):
        """Creates a surface containing the ChoiceList and blits it to the main game surface"""
        #first: figure out how tall our surface has to be
        #we know that we'll always have choices - 1 unselected font renders and 1 selected font render
        height = self.font.size("A")[1] * (len(self.choices) - 1) + (self.selectedItemFont.size("A")[1])

        #next, figure out how wide our surface has to be
        #we do this by finding the longest choice, rendering it in both the unselected font and the selected font
        #and then choosing the wider of the two
        longestChoice = ""

        for choice in self.choices:
            if len(choice) > len(longestChoice):
                longestChoice = choice

        width = max(self.font.size(longestChoice)[0], self.selectedItemFont.size("> %s" % (longestChoice))[0])
        #create the surface we'll render to with the necessary width and height
        tempSurface = pygame.Surface((width, height))
        #ensure that the choices are always visible on the game by first blitting a black square and then the choices onto that
        tempSurface.fill((0, 0, 0))

        #draw all of our strings to the surface
        for x in range(len(self.choices)):
            toAdd = None
            #determine if this is the selected choice or not
            if self.selectedItemIndex == x:
                #use the selected item font instead
                #note: the "False" and "True" controls font antialiasing
                toAdd = self.selectedItemFont.render("> %s" % (self.choices[x]), True, (255, 255, 255))
            else:
                toAdd = self.font.render(self.choices[x], True, (255, 255, 255))
            #blit it onto our surface at the proper x value
            xValue = int(height / len(self.choices)) * x
            tempSurface.blit(toAdd, (0, xValue))

        #the temporary surface is done. blit it to the main surface
        self.surface.blit(tempSurface, (self.x, self.y))

